<template>
  <div class="advanced-handwriting-input">
    <div
      class="input-wrapper"
      :class="{ focused: isFocused, disabled: disabled, error: hasError }"
    >
      <!-- 输入区域 -->
      <div class="input-area">
        <div
          ref="editableDiv"
          class="editable-div"
          :contenteditable="!disabled"
          :data-placeholder="placeholder"
          @input="onInput"
          @focus="onFocus"
          @blur="onBlur"
        ></div>
      </div>
    </div>

    <!-- 错误提示 -->
    <view v-if="errorMessage" class="error-message">
      {{ errorMessage }}
    </view>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, nextTick, watch } from "vue";

interface Props {
  modelValue?: string;
  placeholder?: string;
  disabled?: boolean;
  errorMessage?: string;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: "",
  placeholder: "请输入内容",
  disabled: false,
  errorMessage: "",
});

const emit = defineEmits<{
  (e: "update:modelValue", value: string): void;
  (e: "focus"): void;
  (e: "blur"): void;
  (e: "input"): void;
  (
    e: "buttonClick",
    content: string,
    displayText: string,
    element: HTMLElement
  ): void;
  (e: "insertButtonRequest"): void;
}>();

const editableDiv = ref<HTMLElement | null>(null);
const isFocused = ref(false);
const internalValue = ref("");

// 计算属性
const hasError = computed(() => !!props.errorMessage);
// 解析并设置默认内容，将【】和加减价文本转换为按钮
const parseAndSetContent = (content: string) => {
  if (!editableDiv.value) return;

  // 清空当前内容
  editableDiv.value.innerHTML = '';

  if (!content) return;

  // 解析内容，将【】包裹的内容和"加减价"转换为按钮
  let remainingContent = content;
  
  while (remainingContent.length > 0) {
    // 查找【】的位置
    const openBracketIndex = remainingContent.indexOf('【');
    const tieShuiIndex = remainingContent.indexOf('加减价');
    
    // 如果没有找到【】和加减价，则插入剩余文本
    if (openBracketIndex === -1 && tieShuiIndex === -1) {
      if (remainingContent) {
        editableDiv.value.appendChild(document.createTextNode(remainingContent));
      }
      break;
    }
    
    // 确定下一个要处理的是【】还是加减价
    let nextIndex = -1;
    let isTieShui = false;
    
    if (openBracketIndex !== -1 && tieShuiIndex !== -1) {
      // 都存在，取较前的
      if (openBracketIndex <= tieShuiIndex) {
        nextIndex = openBracketIndex;
        isTieShui = false;
      } else {
        nextIndex = tieShuiIndex;
        isTieShui = true;
      }
    } else if (openBracketIndex !== -1) {
      // 只有【】
      nextIndex = openBracketIndex;
      isTieShui = false;
    } else {
      // 只有加减价
      nextIndex = tieShuiIndex;
      isTieShui = true;
    }
    
    // 插入【】或加减价之前的文本
    if (nextIndex > 0) {
      const textBefore = remainingContent.substring(0, nextIndex);
      editableDiv.value.appendChild(document.createTextNode(textBefore));
    }
    
    if (isTieShui) {
      // 处理加减价
      createAndInsertButtonAtEnd('加减价', '加减价');
      remainingContent = remainingContent.substring(nextIndex + 3); // "加减价"长度为2
    } else {
      // 处理【】
      const closeBracketIndex = remainingContent.indexOf('】', openBracketIndex);
      if (closeBracketIndex !== -1) {
        const buttonText = remainingContent.substring(openBracketIndex + 1, closeBracketIndex);
        const buttonId = `button_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
        createAndInsertButtonAtEnd(buttonId, buttonText);
        remainingContent = remainingContent.substring(closeBracketIndex + 1);
      } else {
        // 没有找到匹配的】，当作普通文本处理
        editableDiv.value.appendChild(document.createTextNode('【'));
        remainingContent = remainingContent.substring(1);
      }
    }
  }

  // 更新 internalValue
  const newContent = editableDiv.value.innerHTML || "";
  internalValue.value = newContent;
  emit("update:modelValue", newContent);
};

// 在末尾创建并插入按钮的辅助函数
const createAndInsertButtonAtEnd = (content: string, displayText: string) => {
  if (!editableDiv.value) return;

  // 创建按钮元素
  const button = document.createElement("span");
  button.contentEditable = "false";
  button.className = "styled-button";
  button.dataset.content = content;
  button.innerHTML = displayText;

  if (content === "加减价" || displayText === "加减价") {
    // 加减价按钮样式
    button.style.cssText = `
      display: inline-block;
      padding: 3px 8px;
      border-radius: 99px;
      background-color: #2678FF;
      color: white;
      font-size: 24rpx;
      cursor: pointer;
      user-select: none;
      box-sizing: border-box;
    `;
  } else {
    // 普通按钮样式
    button.style.cssText = `
      display: inline-block;
      padding: 3px 8px;
      border-radius: 99px;
      background-color: #1D8C29;
      color: white;
      font-size: 24rpx;
      cursor: pointer;
      user-select: none;
      box-sizing: border-box;
    `;
  }

  // 添加点击事件
  button.addEventListener("click", () => {
    emit("buttonClick", content, displayText, button);
  });

  // 插入按钮
  editableDiv.value.appendChild(button);
  // 添加空格避免粘连
  editableDiv.value.appendChild(document.createTextNode(" "));
};
// 修改 updateEditableContent 方法
const updateEditableContent = () => {
  nextTick(() => {
    if (editableDiv.value) {
      if (internalValue.value) {
        // 解析并设置内容
        parseAndSetContent(internalValue.value);
      } else {
        // 如果没有内容，清空
        editableDiv.value.innerHTML = '';
      }
    }
  });
};
// 监听外部值变化
watch(
  () => props.modelValue,
  (newValue) => {
    
    if (newValue !== internalValue.value) {
      internalValue.value = newValue || "";
      updateEditableContent();
    }
  },
  { immediate: true }
);

// 输入处理 - 修复版本
const onInput = (e: Event) => {
  if (props.disabled) return;

  // 延迟一小段时间确保DOM更新完成
  setTimeout(() => {
    if (editableDiv.value) {
      const content = editableDiv.value.innerHTML || "";

      // 只有当内容真正发生变化时才更新
      if (content !== internalValue.value) {
        internalValue.value = content;
        emit("update:modelValue", content);
      }
    }
  }, 0);
};

// 聚焦处理
const onFocus = () => {
  isFocused.value = true;
  emit("focus");
};

// 失焦处理
const onBlur = () => {
  isFocused.value = false;
  emit("blur");
};

// 插入内容到光标位置
const insertContentAtCursor = (text: string) => {
  if (props.disabled || !editableDiv.value) return;

  try {
    const selection = window.getSelection();
    if (!selection || selection.rangeCount === 0) {
      // 无选区时在末尾插入
      const textNode = document.createTextNode(text);
      editableDiv.value.appendChild(textNode);
    } else {
      // 有选区时在光标位置插入
      const range = selection.getRangeAt(0);
      const textNode = document.createTextNode(text);
      range.insertNode(textNode);

      // 移动光标到插入内容之后
      range.setStartAfter(textNode);
      range.setEndAfter(textNode);
      selection.removeAllRanges();
      selection.addRange(range);
    }

    // 更新内容
    const newContent = editableDiv.value.innerHTML || "";
    internalValue.value = newContent;
    emit("update:modelValue", newContent);
  } catch (error) {
    console.error("插入内容失败:", error);
  }
};

// 插入带样式的按钮
const insertButtonAtCursor = (content: string, displayText: string) => {
  if (props.disabled || !editableDiv.value) return;

  try {
    const selection = window.getSelection();

    // 创建按钮元素
    const button = document.createElement("span");
    button.contentEditable = "false";
    button.className = "styled-button";
    button.dataset.content = content;
    button.innerHTML = displayText;
    if (content === "加减价") {
      // 添加样式
      button.style.cssText = `
      display: inline-block;
      padding: 3px 8px;
      border-radius: 99px;
      background-color: #2678FF;
      color: white;
      font-size: 24rpx;
      cursor: pointer;
      user-select: none;
      box-sizing: border-box;
    `;
    } else {
      // 添加样式
      button.style.cssText = `
      display: inline-block;
      padding: 3px 8px;
      border-radius: 99px;
      background-color: #1D8C29;
      color: white;
      font-size: 24rpx;
      cursor: pointer;
      user-select: none;
      box-sizing: border-box;
    `;
    }

    // 添加点击事件，传递按钮元素本身
    button.addEventListener("click", () => {
      emit("buttonClick", content, displayText, button);
    });

    if (!selection || selection.rangeCount === 0) {
      editableDiv.value.appendChild(document.createTextNode(" "));
      // 无选区时在末尾插入
      editableDiv.value.appendChild(button);
      // 添加空格避免粘连
      editableDiv.value.appendChild(document.createTextNode(" "));
    } else {
      // 有选区时在光标位置插入
      const range = selection.getRangeAt(0);
      range.deleteContents();
      range.insertNode(button);

      // 插入空格避免粘连
      const spaceNode = document.createTextNode(" ");
      range.setStartAfter(button);
      range.insertNode(spaceNode);

      // 移动光标到空格之后
      range.setStartAfter(spaceNode);
      range.setEndAfter(spaceNode);
      selection.removeAllRanges();
      selection.addRange(range);
      // 添加空格避免粘连
      editableDiv.value.appendChild(document.createTextNode(" "));
    }

    // 更新内容
    nextTick(() => {
      if (editableDiv.value) {
        const newContent = editableDiv.value.innerHTML || "";
        internalValue.value = newContent;
        emit("update:modelValue", newContent);
      }
    });
  } catch (error) {
    console.error("插入按钮失败:", error);
    // 失败时插入普通文本
    insertContentAtCursor(displayText);
  }
};

// 替换指定按钮为新按钮
const replaceButton = (
  oldButton: HTMLElement,
  newContent: string,
  newDisplayText: string
) => {
  
  if (props.disabled || !editableDiv.value) return;

  try {
    // 创建新按钮
    const newButton = document.createElement("span");
    newButton.contentEditable = "false";
    newButton.className = "styled-button";
    newButton.dataset.content = newContent;
    newButton.innerHTML = newDisplayText;

    // 添加样式
    newButton.style.cssText = `
      display: inline-block;
      padding: 3px 8px;
      border-radius: 99px;
      background-color: #1D8C29;
      color: white;
      font-size: 24rpx;
      cursor: pointer;
      user-select: none;
    `;
    // 添加点击事件
    newButton.addEventListener("click", () => {
      emit("buttonClick", newContent, newDisplayText, newButton);
    });

    // 替换旧按钮
    oldButton.parentNode?.replaceChild(newButton, oldButton);

    // 更新内容
    nextTick(() => {
      if (editableDiv.value) {
        const newContentText = editableDiv.value.innerHTML || "";
        internalValue.value = newContentText;
        emit("update:modelValue", newContentText);
      }
    });
  } catch (error) {
    console.error("替换按钮失败:", error);
  }
};
// 处理HTML内容的函数
const processContent = (htmlContent: string) => {
  // 使用正则表达式匹配 styled-button span 标签
  let result = htmlContent.replace(
    /<span[^>]*class="[^"]*styled-button[^"]*"[^>]*data-content="[^"]*"[^>]*>([^<]*)<\/span>/g,
    (match, content) => {
      // 去除首尾空白字符
      const textContent = content.trim();

      if (textContent === "加减价") {
        // 如果是"加减价"，只返回文本内容，不包含标签
        return textContent;
      } else {
        // 如果不是"加减价"，用【】包裹内容
        return `【${textContent}】`;
      }
    }
  );

  // 移除所有 span 标签，保留其中的内容
  result = result.replace(/<span[^>]*>([^<]*)<\/span>/g, "$1");

  // 移除其他 HTML 标签
  result = result.replace(/<[^>]*>/g, "");

  // 处理常见 HTML 实体
  result = result
    .replace(/&nbsp;/g, " ")
    .replace(/&amp;/g, "&")
    .replace(/&lt;/g, "<")
    .replace(/&gt;/g, ">")
    .replace(/&quot;/g, '"')
    .replace(/&#39;/g, "'");

  return result.trim();
};
// 获取输入框内容
const getContent = () => {
  if (editableDiv.value) {
    const content = editableDiv.value.innerHTML || "";

    return processContent(content);
  }
  return internalValue.value;
};

// 暴露方法给父组件
defineExpose({
  focus: () => {
    if (editableDiv.value) {
      editableDiv.value.focus();
      isFocused.value = true;
    }
  },
  blur: () => {
    if (editableDiv.value) {
      editableDiv.value.blur();
      isFocused.value = false;
    }
  },
  insertContentAtCursor,
  insertButtonAtCursor,
  getContent,
  replaceButton,
  parseAndSetContent, // 暴露解析方法
});

onMounted(() => {
  updateEditableContent();
});
</script>

<style scoped lang="scss">
.advanced-handwriting-input {
  height: 100%;
  .input-wrapper {
    height: 100%;
    // display: flex;
    align-items: center;
    padding: 10rpx 24rpx;
    background: #fff;
    border: 2rpx solid #e5e5e5;
    border-radius: 10rpx;
    transition: all 0.3s;

    &.focused {
      border-color: #007aff;
      box-shadow: 0 0 0 2rpx rgba(0, 122, 255, 0.2);
    }

    &.disabled {
      background-color: #f5f5f5;
      opacity: 0.6;
    }

    &.error {
      border-color: #ff4d4f;
    }

    .input-area {
      flex: 1;
      min-height: 40rpx;
      min-height: 241rpx;
      .editable-div {
        outline: none;
        min-height: 40rpx;
         min-height: 241rpx;
        line-height: 1.5;
        word-break: break-all;
        word-wrap: break-word;
        height: 100%;
        &:empty:before {
          content: attr(data-placeholder);
          color: #ccc;
        }

        .styled-button {
          display: inline-block;
          padding: 4rpx 12rpx;
          margin: 0 4rpx;
          border-radius: 6rpx;
          background-color: #1890ff;
          color: white;
          font-size: 24rpx;
          cursor: pointer;
          user-select: none;
        }
      }
    }
  }

  .error-message {
    color: #ff4d4f;
    font-size: 24rpx;
    margin-top: 10rpx;
    padding-left: 10rpx;
  }
}
</style>
